<?php


namespace app\service;


use app\model\Category;
use app\model\Model;
use app\model\Route;
use app\model\Website;
use think\facade\Cache;

class SitemapService
{
    protected $xmlFilePath;
    protected $domain;
    protected $htmlFilePath;

    /**
     */
    public function makeSitemap($siteId, $sellerId = 1): array
    {
        $this->setXmlPath($siteId);
        $this->setHtmlPath($siteId);
        // 获取当前网站所有的路由
        $routes = $this->getRoute($siteId,$sellerId);
        $routes = $this->dealRoute($routes);
        // 更新网站sitemap html文件
        $this->sitemapHtmlUpdate($routes);

        // 更新网站sitemap文件
        $res =  $this->sitemapUpdate($routes);
        Cache::delete('hc_sitemap_' . $sellerId . '_' . $siteId . '_' . 'html');
        Cache::delete('hc_sitemap_' . $sellerId . '_' . $siteId . '_' . 'xml');
        $res['data'] = 'http://' . $this->domain . '/sitemap_html/' .  $siteId . '_sitemap.html';
        return $res;

    }

    /**
     * 获取站点所有路由
     * @throws \app\exception\ModelEmptyException
     * @throws \app\exception\ModelException
     */
    public function getRoute($siteId, $sellerId=1): array
    {
        // 获取当前域名
        $Website = new Website();
        $website = $Website -> getWebsite(['id'=> $siteId,'seller_id' => $sellerId ])['data'];
        $this->domain = $website['domain'];
        if($website['parent_id'] != 0){
            $category = new Category();
            $cate = $category->getAllCustomData(['seller_id'=>$sellerId,'website_id'=>$siteId])['data'];
            $siteId = $website['parent_id'];
        }
        $Route = new Route();
        $route = $Route->alias('r')
            ->field('r.*')
            ->leftJoin('category c','r.category_id = c.id')
            ->where('r.seller_id',$sellerId)
            ->where('r.website_id',$siteId)
            ->where('r.status',1)
            ->where('c.type','in',[1,4])
            ->select()->toArray();
        $routePath = [];
        if(!empty($route) && !empty($website)){
            $this -> domain = $website['domain'];
            if(isset($cate) && !empty($cate)){
                $cateIds = array_column($cate,'id');
                $parentMap = array_column($cate,'parent_map');
                $cateMap = array_combine($parentMap,$cateIds);
            }
            foreach($route as $val){
                if($val['type'] == 1){
                    // 列表
                    if(preg_match('/:id$/',$val['url'])){
                        if(isset($parentMap) && in_array($val['category_id'],$parentMap)){
                            $val['category_id'] = $cateMap[$val['category_id']];
                        }
                        $SubContent = new SubContent();
                        $contents = $SubContent->alias('s')
                            ->leftJoin('category_sub_content csc','csc.sub_content_id = s.id')
                            ->where('csc.category_id',$val['category_id'])
                            ->where('s.seller_id',$sellerId)
                            ->select()->toArray();
                        if(!empty($contents)){
                            foreach($contents as $content){
                                $url = str_replace(':id',$content['id'],$val['url']);
                                $tmp = [
                                    'url' => $url,
                                    'lang' => $val['lang'],
                                    'title' => $content['title']
                                ];
                                array_push($routePath,$tmp);
                            }
                        }
                    }else{
                        $tmp = [
                            'url' => $val['url'],
                            'lang' => $val['lang'],
                            'title' => $val['category_title']
                        ];
                        array_push($routePath,$tmp);
                    }

                }
                if($val['type'] == 3 && (preg_match($website['domain'],$val['url']) || !preg_match('/http/',$val['url']))){
                    // 单页面
                    array_push($routePath,$val['url']);
                }
                if($val['type'] == 4){
                    $tmp = [
                        'url' => $val['url'],
                        'lang' => $val['lang'],
                        'title' => $val['category_title']
                    ];
                    array_push($routePath,$tmp);
                }
            }
        }
        return $routePath;
    }

    public function dealRoute($data): array
    {
        $routes = [];
        foreach ($data as $val){
            $priority = '';
            if($val['url'] == '/'){
                if($val['lang'] == 'zh'){
                    $url = 'http://' . $this->domain ;
                    $priority = 1;
                }else{
                    $url = 'http://' . $this->domain . '/' .$val['lang'];
                    $priority = 1;
                }
            }else{
                if($val['lang'] == 'zh'){
                    $url = 'http://' . $this->domain . $val['url'];
                }else{
                    $url = 'http://' . $this->domain .$val['lang'].'/'. $val['url'];
                }
            }

            $tmpData = [
                'loc' => $url,
                'priority' => empty($priority) ? 0.6 : $priority,
                'update_time' => date('Y-m-d H:i:s'),
                'title' => $val['title']
            ];
            array_push($routes,$tmpData);
        }
        return $routes;
    }

    public function sitemapHtmlUpdate($route)
    {
        // 读取模版文件
        $commonPath = $this->getCommonHtmlPath();
        $content = file_get_contents($commonPath);

        $html = '';
        foreach($route as $val){
            $loc = $val['loc'];
            $title = $val['title'];
            $update_time = $val['update_time'];
            $priority = $val['priority'];
            $html .= "<li>\n<div class='T1'><a href='$loc'>$title</a></div>\n<div class='T2'> $update_time</div>\n<div class='T3'>Always</div>\n<div class='T4'>$priority</div>\n</li>\n";
        }
        $html .= '</ul>';
        $realHtml = str_replace('</ul>',$html,$content);
        @file_put_contents($this->htmlFilePath,$realHtml);
    }

    /**
     * xml文件更新
     * @param $route
     * @return array
     */
    public function sitemapUpdate($route): array
    {
        try{
            $this->xmlWrite($this->xmlFilePath, $route);
        }catch (\Exception $e){
            return dataReturn(-1,$e->getMessage());
        }
        return dataReturn(0,'success');
    }

    /**
     * 写xml文件
     * @param $path
     * @param $data
     */
    public function xmlWrite($path, $data) {
        // xml文件生成
        header("Content-type: text/html; charset=utf-8");

        $xml = new \XMLWriter();

        $xml->openUri($path);

        // 设置缩进字符串
        $xml->setIndentString("\t");
        $xml->setIndent(true);

        // xml文档开始
        $xml->startDocument('1.0', 'utf-8');

        // 创建根节点
        $xml->startElement("urlset");
        $xml->writeAttribute('xmlns','http://www.sitemaps.org/schemas/sitemap/0.9');
        if ($data) {
            foreach ($data as $value) {
                $loc = !empty($value['loc']) ? $value['loc'] : '';
                $priority = !empty($value['priority']) ? $value['priority'] : '0.6';
                $lastmod = !empty($value['update_time']) ? $value['update_time'] : date('Y-m-d H:i:s');
                $changefreq = !empty($value['changefreq']) ? $value['changefreq'] : 'Always';

                // 节点1
                $xml->startElement("url");
                $xml->startElement("loc");
                $xml->text($loc);
                $xml->endElement();

                $xml->startElement("priority");
                $xml->text($priority);
                $xml->endElement();

                $xml->startElement("lastmod");
                $xml->text($lastmod);
                $xml->endElement();

                $xml->startElement("changefreq");
                $xml->text($changefreq);
                $xml->endElement();
                $xml->endElement();
            }
        }
        $xml->endElement();
    }

    private function getCommonHtmlPath(): string
    {
        return CMS_ROOT . 'public' . DIRECTORY_SEPARATOR . 'sitemap_html' . DIRECTORY_SEPARATOR  .'common.html';
    }

    private function setXmlPath($siteId):void
    {
        $this->xmlFilePath = CMS_ROOT . 'public' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . $siteId .'_sitemap.xml';
    }

    private function setHtmlPath($siteId):void
    {
        $this->htmlFilePath = CMS_ROOT . 'public' . DIRECTORY_SEPARATOR . 'sitemap_html' . DIRECTORY_SEPARATOR . $siteId .'_sitemap.html';
    }

    /**
     * 获取sitemap路径
     * @param $type
     * @param $siteId
     * @param $sellerId
     * @return mixed|string
     */
    public function getSitemap($type,$siteId,$sellerId)
    {
        $sitemapCacheKey = 'hc_sitemap_' . $sellerId . '_' . $siteId . '_' . $type;
        $sitemapPath = Cache::get($sitemapCacheKey);
        $typePath = $type.'FilePath';
        if(empty($sitemapPath)){
            $res = $this->makeSitemap($siteId,$sellerId);
            if($res['code'] == 0){
                $path = $this-> $typePath;
                $href = str_replace(CMS_ROOT . 'public','http://'.$this->domain,$path);
            }else{
                $href = $this->domain;
            }
            Cache::set($sitemapCacheKey,$href);
        }else{
            $href = $sitemapPath;
        }
        return $href;
    }
}